﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace HA.MT3DMS
{
    public static class UcnFileReader
    {
        /// <summary>
        /// 读整个文件
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static List<UcnData> ReadUcnFile(string fileName)
        {
            FileStream fs = new FileStream(fileName, FileMode.Open);

            BinaryReader reader = new BinaryReader(fs);

            List<UcnData> result = new List<UcnData>();

            try
            {
                //while (reader.PeekChar() != -1)  //这句是微软的bug
                while (reader.BaseStream.Position < reader.BaseStream.Length) 
                {
                    UcnData ucnObj = new UcnData();

                    //reader.BaseStream.Position = 0;

                    ucnObj.NTRANS = reader.ReadInt32();  //传输步长
                    ucnObj.KSTP = reader.ReadInt32();  //// '时间不长
                    ucnObj.KPER = reader.ReadInt32();  // // '应力期
                    ucnObj.TOTIM = reader.ReadSingle();  // '逝去时间
                    ucnObj.TEXT = reader.ReadChars(16);  // 'concentration
                    ucnObj.NCOL = reader.ReadInt32();  // '列
                    ucnObj.NROW = reader.ReadInt32();  // '行          
                    ucnObj.ILAY = reader.ReadInt32();  //'层

                    bool isExist = false;
                    UcnData existData = null;

                    foreach (UcnData data in result)
                    {
                        if (data.TOTIM == ucnObj.TOTIM)
                        {
                            isExist = true;
                            existData = data;
                            break;
                        }
                    }

                    if (isExist == true)
                    {
                        float[, ,] values = existData.values.Clone() as float[, ,];
                       
                        existData.values = new float[ucnObj.ILAY, ucnObj.NROW, ucnObj.NCOL];

                        for (int i = 0; i < existData.ILAY; i++)
                        {
                            for (int j = 0; j < ucnObj.NROW; j++)
                            {
                                for (int k = 0; k < ucnObj.NCOL; k++)
                                {
                                    existData.values[i, j, k] = values[i, j, k];
                                }
                            }
                        }

                        existData.ILAY = ucnObj.ILAY;

                        for (int i = existData.ILAY-1; i < existData.ILAY; i++)
                        {
                            for (int j = 0; j < ucnObj.NROW; j++)
                            {
                                for (int k = 0; k < ucnObj.NCOL; k++)
                                {
                                    existData.values[i, j, k] = reader.ReadSingle();
                                }
                            }
                        }
                    }
                    else
                    {
                        ucnObj.values = new float[ucnObj.ILAY, ucnObj.NROW, ucnObj.NCOL];

                        for (int i = 0; i < 1; i++)
                        {
                            for (int j = 0; j < ucnObj.NROW; j++)
                            {
                                for (int k = 0; k < ucnObj.NCOL; k++)
                                {
                                    ucnObj.values[i, j, k] = reader.ReadSingle();
                                }
                            }
                        }
                        result.Add(ucnObj);
                    }
                } 

                fs.Close();
                fs.Dispose();
                reader.Close();
                reader.Dispose();

                return result ;

            }
            catch (Exception ex)
            {
                fs.Close();
                fs.Dispose();
                reader.Close();
                reader.Dispose();

                return null ;
            }
        }

        /// <summary>
        /// 返回这个文件共有多少段，引用传递值存单个段落有多少字节
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="partLength">存储单段字节数</param>
        /// <returns></returns>
        public static int GetUcnNum(string fileName,ref long partLength)
        {
            FileStream fs = new FileStream(fileName, FileMode.Open);

            BinaryReader reader = new BinaryReader(fs);

            long length = reader.BaseStream.Length;

            if (length == 0)
            {
                fs.Close();
                reader.Close();
                return 0;
            }

            long singleLength = 0;

            try
            {
                //if (reader.PeekChar() != -1)
                    if (reader.BaseStream.Position < reader.BaseStream.Length) 
                {
                    UcnData ucnObj = new UcnData();

                    //reader.BaseStream.Position = 0;

                    ucnObj.NTRANS = reader.ReadInt32();  //传输步长
                    singleLength += 4;
                    ucnObj.KSTP = reader.ReadInt32();  //// '时间不长
                    singleLength += 4;
                    ucnObj.KPER = reader.ReadInt32();  // // '应力期
                    singleLength += 4;
                    ucnObj.TOTIM = reader.ReadSingle();  // '逝去时间
                    singleLength += 4;
                    ucnObj.TEXT = reader.ReadChars(16);  // 'concentration
                    singleLength += 16;
                    ucnObj.NCOL = reader.ReadInt32();  // '列
                    singleLength += 4;
                    ucnObj.NROW = reader.ReadInt32();  // '行          
                    singleLength += 4;
                    ucnObj.ILAY = reader.ReadInt32();  //'层
                    singleLength += 4;

                    ucnObj.values = new float[ucnObj.ILAY, ucnObj.NROW, ucnObj.NCOL];

                    for (int i = 0; i < ucnObj.ILAY; i++)
                    {
                        for (int j = 0; j < ucnObj.NROW; j++)
                        {
                            for (int k = 0; k < ucnObj.NCOL; k++)
                            {
                                ucnObj.values[i, j, k] = reader.ReadSingle();
                                singleLength += 4;
                            }
                        }
                    }


                }

                fs.Close();
                fs.Dispose();
                reader.Close();
                reader.Dispose();

                partLength = singleLength;

                int num;
                if (singleLength == 0)
                {
                    num = 0;
                }
                else
                {
                    long n = length / singleLength;
                    num = Convert.ToInt32(n);
                }

                return num;

            }
            catch (Exception ex)
            {
                fs.Close();
                fs.Dispose();
                reader.Close();
                reader.Dispose();

                return 0;
            }
            
        }

        /// <summary>
        /// 读取任意index段的内容。
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="index">要读哪一段的</param>
        /// <param name="partLength">单段有多少字节</param>
        /// <returns></returns>
        public static UcnData ReadUcnFile(string fileName, int index , long partLength)
        {
            FileStream fs = new FileStream(fileName, FileMode.Open);

            BinaryReader reader = new BinaryReader(fs);

            reader.BaseStream.Position = partLength;

            UcnData ucnObj = new UcnData();

            try
            {

                //if (reader.PeekChar() != -1)
                if (reader.BaseStream.Position < reader.BaseStream.Length) 
                {
                    //reader.BaseStream.Position = 0;

                    ucnObj.NTRANS = reader.ReadInt32();  //传输步长
                    ucnObj.KSTP = reader.ReadInt32();  //// '时间不长
                    ucnObj.KPER = reader.ReadInt32();  // // '应力期
                    ucnObj.TOTIM = reader.ReadSingle();  // '逝去时间
                    ucnObj.TEXT = reader.ReadChars(16);  // 'concentration
                    ucnObj.NCOL = reader.ReadInt32();  // '列
                    ucnObj.NROW = reader.ReadInt32();  // '行          
                    ucnObj.ILAY = reader.ReadInt32();  //'层

                    ucnObj.values = new float[ucnObj.ILAY, ucnObj.NROW, ucnObj.NCOL];

                    for (int i = 0; i < ucnObj.ILAY; i++)
                    {
                        for (int j = 0; j < ucnObj.NROW; j++)
                        {
                            for (int k = 0; k < ucnObj.NCOL; k++)
                            {
                                ucnObj.values[i, j, k] = reader.ReadSingle();
                            }
                        }
                    }

                    fs.Close();
                    fs.Dispose();
                    reader.Close();
                    reader.Dispose();

                    return ucnObj;

                }

                fs.Close();
                fs.Dispose();
                reader.Close();
                reader.Dispose();

                return null;
               
                

            }
            catch (Exception ex)
            {
                fs.Close();
                fs.Dispose();
                reader.Close();
                reader.Dispose();

                return null;
            }
            
            
        }

    }
}
